package com.web.cloud.base.dao.provider;

import com.web.cloud.utils.TableSearchColumnHelper;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.scripting.xmltags.*;
import tk.mybatis.mapper.entity.EntityColumn;
import tk.mybatis.mapper.mapperhelper.EntityHelper;
import tk.mybatis.mapper.mapperhelper.MapperHelper;
import tk.mybatis.mapper.mapperhelper.MapperTemplate;
import tk.mybatis.mapper.mapperhelper.SqlHelper;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

/**
 * 通用查询Provider
 * Created by liuhaiming on 2015/8/27
 */
public class CommonSelectMapperProvider extends MapperTemplate {
    private static final String entityName = "record";

    public CommonSelectMapperProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
        super(mapperClass, mapperHelper);
    }

    public String select(MappedStatement ms, Class<?> entityClass) {
        this.setResultType(ms, entityClass);
        return SqlHelper.selectAllColumns(entityClass) + SqlHelper.fromTable(entityClass, this.tableName(entityClass)) + this.whereAllIfColumns(entityClass, this.isNotEmpty(), (TableSearchColumnHelper.TableSearchColumn)null) + SqlHelper.orderByDefault(entityClass);
    }

    private String whereAllIfColumns(Class<?> entityClass, boolean empty, TableSearchColumnHelper.TableSearchColumn searchColumn) {
        StringBuilder sql = new StringBuilder();
        sql.append("<where>");
        Set columnList = EntityHelper.getColumns(entityClass);
        Iterator var6 = columnList.iterator();

        while(var6.hasNext()) {
            EntityColumn column = (EntityColumn)var6.next();
            sql.append(SqlHelper.getIfNotNull("record", column, " AND " + column.getColumnEqualsHolder("record"), empty));
        }

        if(searchColumn != null) {
            sql.append(" AND ").append(searchColumn.getColumn()).append(" like CONCAT(\'%\', #{searchValue}, \'%\') ");
        }

        sql.append("</where>");
        return sql.toString();
    }

    public String selectLike(MappedStatement ms) {
        Class entityClass = this.getEntityClass(ms);
        this.setResultType(ms, entityClass);
        List searchColumns = TableSearchColumnHelper.getTableSearchColumns(entityClass);
        if(searchColumns.isEmpty()) {
            return this.select(ms, entityClass);
        } else {
            StringBuilder sql = new StringBuilder();
            int index = 0;
            sql.append(" select DISTINCT * FROM ( ");
            Iterator var6 = searchColumns.iterator();

            while(var6.hasNext()) {
                TableSearchColumnHelper.TableSearchColumn searchColumn = (TableSearchColumnHelper.TableSearchColumn)var6.next();
                if(StringUtils.isEmpty(searchColumn.getJoinTable())) {
                    sql.append(SqlHelper.selectAllColumns(entityClass));
                    sql.append(SqlHelper.fromTable(entityClass, this.tableName(entityClass)));
                    sql.append(this.whereAllIfColumns(entityClass, this.isNotEmpty(), searchColumn));
                }

                ++index;
                if(searchColumns.size() != index) {
                    sql.append(" UNION ALL ");
                }
            }

            sql.append(" ) t ");
            return sql.toString();
        }
    }

    public SqlNode selectByIdList(MappedStatement ms) {
        Class entityClass = this.getEntityClass(ms);
        this.setResultType(ms, entityClass);
        LinkedList sqlNodes = new LinkedList();
        sqlNodes.add(new StaticTextSqlNode("SELECT " + EntityHelper.getSelectColumns(entityClass) + " FROM " + this.tableName(entityClass)));
        LinkedList whereNodes = new LinkedList();
        whereNodes.add(new StaticTextSqlNode(" dr = 0 "));
        ForEachSqlNode forEachSqlNode = new ForEachSqlNode(ms.getConfiguration(), new StaticTextSqlNode("#{item}"), "list", "index", "item", " and id in (", ")", ",");
        whereNodes.add(forEachSqlNode);
        sqlNodes.add(new WhereSqlNode(ms.getConfiguration(), new MixedSqlNode(whereNodes)));
        String orderByClause = EntityHelper.getOrderByClause(entityClass);
        if(orderByClause.length() > 0) {
            sqlNodes.add(new StaticTextSqlNode("ORDER BY " + orderByClause));
        }

        return new MixedSqlNode(sqlNodes);
    }
}
